java String 的+操作导致的问题

定义

  在java中 null既不是对象,也不是一种类型,而是一种特殊的值。在这里我要说的是一种特殊情况哈。

编译器自带的优化

  总所周知,我们的java代码中String对象那如果直接用+连连接字符串可能导致效率变低。但是现在在java1.5以后编译器对其自动做了优化,如果你有时间打开反编译的源码看看,你会发现,String a=”b”+”cc”;这个代码在编译器中优化了,优化方式为在这行代码的开始的地方声明一个StringBuilder,然后不断append后面的字符串。因此对于java来说你用StringBuilder和String的+其实效率都是一样的,但是为了保证一个良好的习惯还是用StringBuilder好一点。

+导致的问题

  我们用””+null,这个空对象,会生成一个null字符串。这是为什么呢?
  前文已经提到,我们已经用编译器做了优化,String对象的+被优化为了StringBuilder的append,然而我们看看append的源码,你就会发现为何是null字符串了。


         public StringBuilder append(Object obj) {
            return append(String.valueOf(obj));
        }

        @Override
        public StringBuilder append(String str) {
            super.append(str);
            return this;
        }

  查看源码发现,append方法向上调用了其抽象类AbstractStringBuilder方法的append方法,在看

     public AbstractStringBuilder append(String str) {
            if (str == null)
                return appendNull();
            int len = str.length();
            ensureCapacityInternal(count + len);
            str.getChars(0, len, value, count);
            count += len;
            return this;
        }
     private AbstractStringBuilder appendNull() {
            int c = count;
            ensureCapacityInternal(c + 4);
            final char[] value = this.value;
            value[c++] = 'n';
            value[c++] = 'u';
            value[c++] = 'l';
            value[c++] = 'l';
            count = c;
            return this;
        }

  你看真相大白了,在这个抽象类的这个append方法中,先进行了判断,如果为null,则是把这个null作为一个字符串加上去。因此解决了上面我们遇到的问题,为何String对象+null,会条件一个null字符串。   测试案例如下:

    public static void main(String[] args) {
            String a="dh";
            String b=a+null;
            System.out.println(b);

        }
  结果如下:
    dhnull